package org.jeecg.activiti.controller;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.jeecg.activiti.entity.ActReModelExtend;
import org.jeecg.activiti.entity.ModelExtend;
import org.jeecg.activiti.service.IActReModelExtendService;
import org.jeecg.activiti.service.IActivitiModelService;
import org.jeecg.common.api.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * 流程模型管理
 */
@RestController
@RequestMapping("/activiti/models")
@Api(tags = "流程定义管理")
public class ActivitiModelController {

    @Autowired
    private IActReModelExtendService iActReModelExtendService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private IActivitiModelService iActivitiModelService;

    /**
     * 查询流程定义列表
     * @param pageNo
     * @param pageSize
     * @param request
     * @return
     */
    @GetMapping("/list")
    @ApiOperation(value = "获取流程定义列表", notes = "获取流程定义列表")
    public Result<IPage<ModelExtend>> getModelList(ModelExtend modelE,
                               @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
                               @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest request){
        Result<IPage<ModelExtend>> result = new Result<>();

        Page<ActReModelExtend> page = new Page<>(pageNo, pageSize);
        IPage<ModelExtend> pageList = iActReModelExtendService.selectListByPage(page, modelE);

        result.setSuccess(true);
        result.setResult(pageList);

        return result;
    }

    /**
     * 无分页查询流程定义列表
     * @param request
     * @return
     */
    @GetMapping("/listAll")
    @ApiOperation(value = "无分页获取流程定义列表", notes = "无分页获取流程定义列表")
    public Result<Object> getModelListAll(ModelExtend modelE,HttpServletRequest request){

     	List<ModelExtend> modelExtends =  this.iActivitiModelService.getModelListAll(modelE);
        return Result.OK(modelExtends);
    }

    /**
     * 保存流程定义
     * @return
     */
    @PostMapping("/save")
    @ApiOperation(value = "流程定义新增", notes = "获取取流程定义新增")
    public Result<Object> saveModel(@RequestBody ModelExtend modelExtend) {
        try {
            //初始化一个空模型
            Model model = repositoryService.newModel();
            //设置一些默认信息
            int revision = 1;
            String name = modelExtend.getName();
            String description = modelExtend.getDescription();
            String key = modelExtend.getKey();
            String businessPlate = modelExtend.getBusinessPlate();
            String icon = modelExtend.getIcon();
            boolean isShow = modelExtend.getIsShow();

            if (StrUtil.isBlank(name)){
                name = "new-process";
            }

            if (StrUtil.isBlank(description)){
                description = "description";
            }

            if (StrUtil.isBlank(key)){
                key = "processKey";
            }


            ObjectNode modelNode = objectMapper.createObjectNode();
            modelNode.put("name", name);
            modelNode.put("description", description);
            modelNode.put("revision", revision);

            model.setName(name);
            model.setKey(key);
            model.setMetaInfo(modelNode.toString());
            repositoryService.saveModel(model);
            String id = model.getId();

            //完善ModelEditorSource
            ObjectNode editorNode = objectMapper.createObjectNode();
            editorNode.put("id", "canvas");
            editorNode.put("resourceId", "canvas");
            ObjectNode stencilSetNode = objectMapper.createObjectNode();
            stencilSetNode.put("namespace",
                    "http://b3mn.org/stencilset/bpmn2.0#");
            editorNode.replace("stencilset", stencilSetNode);
            repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));


            // 保存流程模型扩展
            ActReModelExtend actReModelExtend = new ActReModelExtend();
            actReModelExtend.setBusinessPlate(businessPlate);
            actReModelExtend.setIcon(icon);
            actReModelExtend.setModelId(model.getId());
            actReModelExtend.setIsShow(isShow);
            actReModelExtend.setDescription(description);
            actReModelExtend.setIsDel(false);
            iActReModelExtendService.save(actReModelExtend);

            return Result.OK();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return Result.error("流程定义创建失败！");
        }
    }

    /**
     * 删除模型
     * @param id
     * @return
     */
    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    @ApiOperation(value = "流程定义删除", notes = "流程定义删除")
    public Result<Object>  delete(@ApiParam(name="id", value = "流程定义ID", required = true) @RequestParam(name="id",required=true) String id){
        // 删除流程定义
        iActReModelExtendService.update(new UpdateWrapper<ActReModelExtend>().set("is_del", true).eq("model_id", id));
        return Result.OK("删除成功！",null);
    }

    /**
     * 批量删除模型
     */
    @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE)
    @ApiOperation(value = "流程定义批量删除", notes = "流程定义批量删除")
    public Result<Object> deleteBatch(@ApiParam(name="ids", value = "流程定义IDS", required = true) @RequestParam(name="ids",required=true) String ids) {
        String[] idArr = ids.split(",");
        for (String id : idArr) {
            iActReModelExtendService.update(new UpdateWrapper<ActReModelExtend>().set("is_del", true).eq("model_id", id));
        }
        return Result.OK("批量删除成功。",null);
    }

    /**
     * 编辑模型
     * @return
     */
    @PostMapping("/edit")
    @ApiOperation(value = "流程定义编辑", notes = "流程定义编辑")
    public Result<Object> editModel(@RequestBody ModelExtend modelExtend){
        String businessPlate = modelExtend.getBusinessPlate();
        String icon = modelExtend.getIcon();
        boolean isShow = modelExtend.getIsShow();
        String modelId = modelExtend.getId();
        String description = modelExtend.getDescription();

        // 保存流程模型扩展
        ActReModelExtend actReModelExtend = new ActReModelExtend();
        actReModelExtend.setBusinessPlate(businessPlate);
        actReModelExtend.setIcon(icon);
        actReModelExtend.setModelId(modelId);
        actReModelExtend.setIsShow(isShow);
        actReModelExtend.setDescription(description);
        iActReModelExtendService.update(actReModelExtend, new UpdateWrapper<ActReModelExtend>().eq("model_id", modelId));
        return Result.OK();
    }

    /**
     * 发布流程
     * @param modelId
     * @return
     */
    @GetMapping("/deployment")
    @ApiOperation(value = "流程定义部署", notes = "流程定义部署")
    public @ResponseBody Result<Object> deploy(@ApiParam(name="modelId", value = "流程定义ID", required = true) @RequestParam("modelId") String modelId) {

        try {
        	return this.iActivitiModelService.deploy(modelId);
        } catch (Exception e) {
            String err = e.toString();
            e.printStackTrace();
            if (err.indexOf("NCName") > -1) {
                return Result.error("发布失败：流程设计中的流程名称不能为空，不能为数字以及特殊字符开头！");
            }
            if (err.indexOf("PRIMARY") > -1) {
                return Result.error("发布失败：该模型已发布，key唯一！");
            }
            return Result.error("发布失败！");
        }
    }

    /**
     * 发布流程
     * @param modelId
     * @return
     */
    @GetMapping("/checkKey")
    @ApiOperation(value = "流程定义部署", notes = "流程定义部署")
    public Result<Object> checkKey(@ApiParam(name="modelId", value = "流程定义ID") String modelId, @ApiParam(name="key", value = "流程定义key", required = true)  @RequestParam("key") String key) {

        List<Map<String, Object>> modelList = iActivitiModelService.selectModelByKey(key);
        boolean result = true;
        if (!StringUtils.isEmpty(modelId)) {
            for (Map model : modelList) {
                if (!model.get("ID_").toString().equals(modelId)) {
                    result = false;
                    break;
                } else {
                	result = true;
                }
            }
        } else {
            if (modelList.size() != 0) {
                result = false;
            }
        }

        if (!result) {
            return Result.error("编码已存在，请更换编码");
        } else {
            return Result.OK();
        }
    }
}
